﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

namespace cn.Util
{
    public class ImageTools
    {
        public enum ImageType
        {
            /// <summary>
            /// 大图
            /// </summary>
            L,
            /// <summary>
            /// 小图
            /// </summary>
            M
        }
        /// <summary>
        /// 图片文件名称，以时间命名
        /// </summary>
        /// <returns></returns>
        string GetImageName
        {
            get
            {
                Random rd = new Random();
                StringBuilder serial = new StringBuilder();
                serial.Append(DateTime.Now.ToString("yyyyMMddHHmmssff"));
                serial.Append(rd.Next(0, 999999).ToString());
                return serial.ToString();
            }
        }
        /// <summary>
        /// 上传图片操作
        /// </summary>
        /// <param name="postedFile">客户端图片文件</param>
        /// <param name="dir">文件保存目录</param>
        /// <param name="strategy">缩略图策略，0：保留原图不生成缩略图、1：保留原图并裁剪图片、2：保留原图并缩小图片、3：只裁剪图片、4：只缩小图片</param>
        /// <param name="width">图片宽度</param>
        /// <param name="height">图片高度</param>
        /// <param name="imageUrl">输出，图片地址</param>
        /// <param name="errorMessage">输出，错误信息</param>
        /// <returns></returns>
        public bool UpLoadImg(System.Web.HttpPostedFile postedFile, string dir, int strategy, int width, int height, out string imageUrl, out string errorMessage)
        {
            bool isSuccess = true; errorMessage = string.Empty; imageUrl = string.Empty;
            string imgType = Path.GetExtension(postedFile.FileName);
            if (!ImageTools.IsWebImage(imgType))
            {
                errorMessage = "文件类型必须为.jpg|.gif|.jpeg|.png|.bmp";
                isSuccess = false;
            }
            if (isSuccess && postedFile.ContentLength / 1024 > 500)
            {
                errorMessage = "文件类型必须为.jpg|.gif|.jpeg|.png|.bmp";
                isSuccess = false;
            }
            if (isSuccess)
            {
                Image img = Image.FromStream(postedFile.InputStream, true);
                isSuccess = CreateMiniature(img, postedFile.FileName, dir, strategy, width, height, out imageUrl);
            }
            return isSuccess;
        }
        /// <summary>
        /// 判断文件类型是否为WEB格式图片
        /// (注：JPG,GIF,BMP,PNG)
        /// </summary>
        /// <param name="contentType">HttpPostedFile.ContentType</param>
        /// <returns></returns>
        public static bool IsWebImage(string contentType)
        {
            if (contentType == ".jpeg" || contentType == ".jpg" || contentType == ".gif" || contentType == ".bmp" || contentType == ".png")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 生成等比例高清晰缩略图
        /// </summary>
        /// <param name="image">原图</param>
        /// <param name="newPath">生成的缩略图的路径（虚拟路径） </param>
        /// <param name="width">要生成的缩略图的宽度 </param>
        /// <param name="height">要生成的缩略图的高度 </param>
        /// <returns>返回是否成功</returns>
        public bool CreateMiniature(Image image, string newPath, int width, int height)
        {
            bool result = false;
            double w = 0.0;
            double h = 0.0;
            double mw = Convert.ToDouble(width);
            double mh = Convert.ToDouble(height);
            string newPathPhysical = newPath;//System.Web.HttpContext.Current.Server.MapPath(newPath);
            try
            {
                if (image != null)
                {
                    //从文件取得图片对象
                    double sw = Convert.ToDouble(image.Width);
                    double sh = Convert.ToDouble(image.Height);
                    if (sw < mw && sh < mh)
                    {
                        w = sw;
                        h = sh;
                    }
                    else if ((sw / sh) > (mw / mh))
                    {
                        w = width;
                        h = (w * sh) / sw;
                    }
                    else
                    {
                        h = height;
                        w = (h * sw) / sh;
                    }
                    //取得图片大小
                    System.Drawing.Size size = new Size(Convert.ToInt32(w), Convert.ToInt32(h));
                    //新建一个bmp图片
                    System.Drawing.Image bitmap = new System.Drawing.Bitmap(size.Width, size.Height);
                    //新建一个画板
                    System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
                    //设置高质量插值法
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                    //设置高质量,低速度呈现平滑程度
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    //清空一下画布
                    g.Clear(Color.Blue);
                    //在指定位置画图
                    g.DrawImage(image, new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
                    new System.Drawing.Rectangle(0, 0, image.Width, image.Height),
                    System.Drawing.GraphicsUnit.Pixel);
                    //保存高清晰度的缩略图
                    bitmap.Save(newPathPhysical, System.Drawing.Imaging.ImageFormat.Jpeg);
                    g.Dispose();
                    image.Dispose();
                    //myFile.Delete();     //删除原图片
                    result = true;
                }
            }
            catch
            {
                result = false;
            }
            return result;
        }
        /// <summary>
        /// 生成图片
        /// </summary>
        /// <param name="img">要操作的图片对象</param>
        /// <param name="fullFilName">要操作的图片对象</param>
        /// <param name="dir">图屁保存目录</param>
        /// <param name="strategy">缩略图策略，0：保留原图不生成缩略图、1：保留原图并裁剪图片、2：保留原图并缩小图片、3：只裁剪图片、4：只缩小图片</param>
        /// <param name="width">图片宽度</param>
        /// <param name="heigth">图片高度</param>
        /// <param name="imageUrl">输出，图片地址</param>
        /// <returns></returns>
        public bool CreateMiniature(Image img, string fullFilName, string dir, int strategy, int width, int height, out string imageUrl)
        {
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            string fileName = fullFilName.Substring(fullFilName.LastIndexOf("\\") + 1);//获取上传图片名称
            string type = fullFilName.Substring(fullFilName.LastIndexOf(".") + 1);//获取图片类型 
            imageUrl = GetImageName + "." + type;
            string bigImgPath = dir + "\\" + ImageType.L.ToString() + "_" + imageUrl;
            try
            {
                if (strategy < 3)
                {
                    img.Save(bigImgPath);//保存大图;
                }
            }
            catch
            {
                return false;
            }
            if (strategy > 0)
            {
                string smallImagePath = dir + "\\" + ImageType.M.ToString() + "_" + imageUrl;
                try
                {
                    if (strategy == 1 || strategy == 3)
                    {
                        ZoomAuto(img, smallImagePath, width, height, "", "");
                    }
                    else if (strategy == 2 || strategy == 4)
                    {
                        CreateMiniature(img, smallImagePath, width, height);
                    }
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            else
            {
                return true;
            }
            // return CreateMiniature(bigImgPath, smallImagePath, 310, 310);
        }
        /// <summary>
        /// 图片裁剪
        /// </summary>
        /// <param name="postedFile">原始图片</param>
        /// <param name="savePath">缩略图存放地址</param>
        /// <param name="targetWidth">指定的最大宽度</param>
        /// <param name="targetHeight">指定的最大高度</param>
        /// <param name="watermarkText">水印文字(为""表示不使用水印)</param>
        /// <param name="watermarkImage">水印图片路径(为""表示不使用水印)</param>
        public static void ZoomAuto(Image initImage,string savePath,Double targetWidth,Double targetHeight,string watermarkText,string watermarkImage)
        {
            //创建目录
            string dir = Path.GetDirectoryName(savePath);
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);

            //原图宽高均小于模版，不作处理，直接保存
            if (initImage.Width <= targetWidth && initImage.Height <= targetHeight)
            {
                //文字水印
                if (watermarkText != "")
                {
                    using (Graphics gWater = Graphics.FromImage(initImage))
                    {
                        System.Drawing.Font fontWater = new Font("黑体", 10);
                        System.Drawing.Brush brushWater = new SolidBrush(Color.White);
                        gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10);
                        gWater.Dispose();
                    }
                }

                //透明图片水印
                if (watermarkImage != "")
                {
                    if (File.Exists(watermarkImage))
                    {
                        //获取水印图片
                        using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage))
                        {
                            //水印绘制条件：原始图片宽高均大于或等于水印图片
                            if (initImage.Width >= wrImage.Width && initImage.Height >= wrImage.Height)
                            {
                                Graphics gWater = Graphics.FromImage(initImage);

                                //透明属性
                                ImageAttributes imgAttributes = new ImageAttributes();
                                ColorMap colorMap = new ColorMap();
                                colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
                                colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
                                ColorMap[] remapTable = { colorMap };
                                imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

                                float[][] colorMatrixElements = {
                                   new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
                                   new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
                                   new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
                                   new float[] {0.0f,  0.0f,  0.0f,  0.5f, 0.0f},//透明度:0.5
                                   new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
                                };

                                ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
                                imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                                gWater.DrawImage(wrImage, new Rectangle(initImage.Width - wrImage.Width, initImage.Height - wrImage.Height, wrImage.Width, wrImage.Height), 0, 0, wrImage.Width, wrImage.Height, GraphicsUnit.Pixel, imgAttributes);

                                gWater.Dispose();
                            }
                            wrImage.Dispose();
                        }
                    }
                }
                //保存
                initImage.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            else
            {
                //缩略图宽、高计算
                double newWidth = initImage.Width > targetWidth ? targetWidth : initImage.Width;
                double newHeight = initImage.Height > targetHeight ? targetHeight : initImage.Height;
                double x = initImage.Width > targetWidth ? (initImage.Width - targetWidth) / 2 : 0;
                double y = initImage.Height > targetHeight ? (initImage.Height - targetHeight) / 2 : 0;

                //生成新图
                //新建一个bmp图片
                Image newImage = new Bitmap((int)newWidth, (int)newHeight);
                //新建一个画板
                Graphics newG = System.Drawing.Graphics.FromImage(newImage);

                //设置质量
                newG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                newG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                //置背景色
                newG.Clear(Color.White);
                //画图
                newG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, newImage.Width, newImage.Height), new System.Drawing.Rectangle((int)x, (int)y, newImage.Width, newImage.Height), System.Drawing.GraphicsUnit.Pixel);

                //文字水印
                if (watermarkText != "")
                {
                    using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(newImage))
                    {
                        System.Drawing.Font fontWater = new Font("宋体", 10);
                        System.Drawing.Brush brushWater = new SolidBrush(Color.White);
                        gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10);
                        gWater.Dispose();
                    }
                }

                //透明图片水印
                if (watermarkImage != "")
                {
                    if (File.Exists(watermarkImage))
                    {
                        //获取水印图片
                        using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage))
                        {
                            //水印绘制条件：原始图片宽高均大于或等于水印图片
                            if (newImage.Width >= wrImage.Width && newImage.Height >= wrImage.Height)
                            {
                                Graphics gWater = Graphics.FromImage(newImage);

                                //透明属性
                                ImageAttributes imgAttributes = new ImageAttributes();
                                ColorMap colorMap = new ColorMap();
                                colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
                                colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
                                ColorMap[] remapTable = { colorMap };
                                imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

                                float[][] colorMatrixElements = {
                                   new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
                                   new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
                                   new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
                                   new float[] {0.0f,  0.0f,  0.0f,  0.5f, 0.0f},//透明度:0.5
                                   new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
                                };

                                ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
                                imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                                gWater.DrawImage(wrImage, new Rectangle(newImage.Width - wrImage.Width, newImage.Height - wrImage.Height, wrImage.Width, wrImage.Height), 0, 0, wrImage.Width, wrImage.Height, GraphicsUnit.Pixel, imgAttributes);
                                gWater.Dispose();
                            }
                            wrImage.Dispose();
                        }
                    }
                }

                //保存缩略图
                newImage.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);

                //释放资源
                newG.Dispose();
                newImage.Dispose();
                initImage.Dispose();
            }
        }
    }
}
